#ifndef TRANFORMATION_H
#define TRANFORMATION_H

/** Fichier définissant une classe de transformation des points de l'espace.
 *
 * Ce fichier contient la déclaration de la classe Transformation.
 *
 * @file Transformation.hpp
 * @author Johan "Solo" Luisier
 *
 * @date 2010
 */

#include "Coord.hpp"
#include "Vecteur.hpp"
#include "MatriceSO3.hpp"

#include <functional>

/** Classe implémentant les transformations de l'espace.
 *
 * Cette classe implémente les transformations de l'espace composées
 * de rotations, translations et homothéties.
 *
 * @todo Trouver le moyen de remplacer le facteur d'homothétie par une matrice
 * diagonale.
 *
 * @author Johan "Solo" Luisier
 *
 * @date 2010
 *
 * @class Transformation "Transformation.hpp" "Algebre/Transformation.hpp"
 */
class Transformation : std::unary_function< Coord, Coord >
{
public:
    Transformation( const MatriceSO3& rot = MatriceSO3(),
                    const Coord& trans = Coord(),
                    const double& rapport = 1.,
                    const bool& trVersLoc = true );
    Transformation( const Transformation& tr );
    ~Transformation();
    Transformation& operator=( const Transformation& tr );
    double operator()( const double& scalaire ) const;
    Coord operator()( const Coord& pt ) const;
    Vecteur operator()( const Vecteur& vec ) const;
    VecteurU operator()( const VecteurU& vec ) const;
    Transformation inverse() const;
   /**
    * Permet d'afficher une instance de Transformation dans un flot de
    * sortie quelconque.
    *
    * @param[in] os flot de sortie.
    * @param[in] tr instance de Transformation à afficher.
    *
    * @return une référence sur le flot de sortie utilisé pour
    * l'écriture.
    */
    friend std::ostream& operator<<( std::ostream& os, const Transformation& tr );
protected:
   /**
    * Rotation à appliquer pour passer d'un système de coordonnées à
    * l'autre.
    */
    MatriceSO3 Rotation;
   /**
    * Translation à appliquer pour passer d'un système de coordonnées à
    * l'autre.
    */
    Coord Translation;
   /**
    * Homothétie à appliquer pour passer d'un système de coordonnées à
    * l'autre.
    */
    double Homothetie;
private:
   /**
    * Permet de savoir dans quel ordre il faut composer les opérations
    * pour passer d'un système de coordonnées à l'autre.
    */
    bool VaVersLocal;
};

#endif // TRANFORMATION_H
